//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections;
using System.Data;
using System.Web.Security;
using DotNetNuke.Common.Utilities;
using DotNetNuke.ComponentModel;
using DotNetNuke.Entities.Host;
using DotNetNuke.Entities.Profile;
using DotNetNuke.Entities.Users;
using DotNetNuke.Security.Membership.Data;
using DotNetNuke.Services.Exceptions;
using AspNetSecurity = System.Web.Security;
namespace DotNetNuke.Security.Membership
{
	public class AspNetMembershipProvider : DotNetNuke.Security.Membership.MembershipProvider
	{
		private DotNetNuke.Security.Membership.Data.DataProvider dataProvider;
		public AspNetMembershipProvider()
		{
			dataProvider = DotNetNuke.Security.Membership.Data.DataProvider.Instance();
			if (dataProvider == null)
			{
				string defaultprovider = DotNetNuke.Data.DataProvider.Instance().DefaultProviderName;
				string dataProviderNamespace = "DotNetNuke.Security.Membership.Data";
				if (defaultprovider == "SqlDataProvider")
				{
					dataProvider = new SqlDataProvider();
				}
				else
				{
					string providerType = dataProviderNamespace + "." + defaultprovider;
					dataProvider = (DataProvider)Framework.Reflection.CreateObject(providerType, providerType, true);
				}
				ComponentFactory.RegisterComponentInstance<DataProvider>(dataProvider);
			}
		}
		private bool AutoUnlockUser(AspNetSecurity.MembershipUser aspNetUser)
		{
			if (Host.AutoAccountUnlockDuration != 0)
			{
				if (aspNetUser.LastLockoutDate < System.DateTime.Now.AddMinutes(-1 * Host.AutoAccountUnlockDuration))
				{
					if (aspNetUser.UnlockUser())
					{
						return true;
					}
				}
			}
			return false;
		}
		private UserCreateStatus CreateDNNUser(ref UserInfo user)
		{
			PortalSecurity objSecurity = new PortalSecurity();
			string userName = objSecurity.InputFilter(user.Username, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			string email = objSecurity.InputFilter(user.Email, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			string lastName = objSecurity.InputFilter(user.LastName, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			string firstName = objSecurity.InputFilter(user.FirstName, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			UserCreateStatus createStatus = UserCreateStatus.Success;
			string displayName = objSecurity.InputFilter(user.DisplayName, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			bool updatePassword = user.Membership.UpdatePassword;
			bool isApproved = user.Membership.Approved;
			try
			{
				user.UserID = Convert.ToInt32(dataProvider.AddUser(user.PortalID, userName, firstName, lastName, user.AffiliateID, user.IsSuperUser, email, displayName, updatePassword, isApproved,
				UserController.GetCurrentUserInfo().UserID));
			}
			catch (Exception ex)
			{
				DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
				user = null;
				createStatus = UserCreateStatus.ProviderError;
			}
			return createStatus;
		}
		private UserCreateStatus CreateMemberhipUser(UserInfo user)
		{
			PortalSecurity objSecurity = new PortalSecurity();
			string userName = objSecurity.InputFilter(user.Username, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			string email = objSecurity.InputFilter(user.Email, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			AspNetSecurity.MembershipCreateStatus objStatus = AspNetSecurity.MembershipCreateStatus.Success;
			AspNetSecurity.MembershipUser objMembershipUser;
			if (MembershipProviderConfig.RequiresQuestionAndAnswer)
			{
				objMembershipUser = AspNetSecurity.Membership.CreateUser(userName, user.Membership.Password, email, user.Membership.PasswordQuestion, user.Membership.PasswordAnswer, true, out objStatus);
			}
			else
			{
				objMembershipUser = AspNetSecurity.Membership.CreateUser(userName, user.Membership.Password, email, null, null, true, out objStatus);
			}
			UserCreateStatus createStatus = UserCreateStatus.Success;
			switch (objStatus)
			{
				case AspNetSecurity.MembershipCreateStatus.DuplicateEmail:
					createStatus = UserCreateStatus.DuplicateEmail;
					break;
				case AspNetSecurity.MembershipCreateStatus.DuplicateProviderUserKey:
					createStatus = UserCreateStatus.DuplicateProviderUserKey;
					break;
				case AspNetSecurity.MembershipCreateStatus.DuplicateUserName:
					createStatus = UserCreateStatus.DuplicateUserName;
					break;
				case AspNetSecurity.MembershipCreateStatus.InvalidAnswer:
					createStatus = UserCreateStatus.InvalidAnswer;
					break;
				case AspNetSecurity.MembershipCreateStatus.InvalidEmail:
					createStatus = UserCreateStatus.InvalidEmail;
					break;
				case AspNetSecurity.MembershipCreateStatus.InvalidPassword:
					createStatus = UserCreateStatus.InvalidPassword;
					break;
				case AspNetSecurity.MembershipCreateStatus.InvalidProviderUserKey:
					createStatus = UserCreateStatus.InvalidProviderUserKey;
					break;
				case AspNetSecurity.MembershipCreateStatus.InvalidQuestion:
					createStatus = UserCreateStatus.InvalidQuestion;
					break;
				case AspNetSecurity.MembershipCreateStatus.InvalidUserName:
					createStatus = UserCreateStatus.InvalidUserName;
					break;
				case AspNetSecurity.MembershipCreateStatus.ProviderError:
					createStatus = UserCreateStatus.ProviderError;
					break;
				case AspNetSecurity.MembershipCreateStatus.UserRejected:
					createStatus = UserCreateStatus.UserRejected;
					break;
			}
			return createStatus;
		}
		private bool DeleteMembershipUser(UserInfo user)
		{
			bool retValue = true;
			try
			{
				AspNetSecurity.Membership.DeleteUser(user.Username, true);
			}
			catch (Exception ex)
			{
				retValue = false;
			}
			return retValue;
		}
		private void FillUserMembership(AspNetSecurity.MembershipUser aspNetUser, UserInfo user)
		{
			if (aspNetUser != null)
			{
				if (user.Membership == null)
				{
					user.Membership = new UserMembership(user);
				}
				user.Membership.CreatedDate = aspNetUser.CreationDate;
				user.Membership.LastActivityDate = aspNetUser.LastActivityDate;
				user.Membership.LastLockoutDate = aspNetUser.LastLockoutDate;
				user.Membership.LastLoginDate = aspNetUser.LastLoginDate;
				user.Membership.LastPasswordChangeDate = aspNetUser.LastPasswordChangedDate;
				user.Membership.LockedOut = aspNetUser.IsLockedOut;
				user.Membership.PasswordQuestion = aspNetUser.PasswordQuestion;
				user.Membership.IsDeleted = user.IsDeleted;
				if (user.IsSuperUser)
				{
					user.Membership.Approved = aspNetUser.IsApproved;
				}
			}
		}
		private AspNetSecurity.MembershipUser GetMembershipUser(UserInfo user)
		{
			return GetMembershipUser(user.Username);
		}
		private AspNetSecurity.MembershipUser GetMembershipUser(string userName)
		{
			string cacheKey = String.Format("MembershipUser_{0}", userName);
			return CBO.GetCachedObject<AspNetSecurity.MembershipUser>(new CacheItemArgs(cacheKey,
																						DataCache.UserCacheTimeOut,
																						DataCache.UserCachePriority,
																						userName),
																	  GetMembershipUserCallBack);
		}

		private static object GetMembershipUserCallBack(CacheItemArgs cacheItemArgs)
		{
			string userName = cacheItemArgs.ParamList[0].ToString();

			return AspNetSecurity.Membership.GetUser(userName);
		}
		private static int GetTotalRecords(ref IDataReader dr)
		{
			int total = 0;
			if (dr.Read())
			{
				try
				{
					total = Convert.ToInt32(dr["TotalRecords"]);
				}
				catch (Exception ex)
				{
					total = -1;
				}
			}
			return total;
		}
		private UserInfo GetUserByAuthToken(int portalId, string userToken, string authType)
		{
			IDataReader dr = dataProvider.GetUserByAuthToken(portalId, userToken, authType);
			UserInfo objUserInfo = UserController.FillUserInfo(portalId, dr, true);
			return objUserInfo;
		}
		private void UpdateUserMembership(UserInfo user)
		{
			PortalSecurity objSecurity = new PortalSecurity();
			string email = objSecurity.InputFilter(user.Email, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			AspNetSecurity.MembershipUser objMembershipUser;
			objMembershipUser = AspNetSecurity.Membership.GetUser(user.Username);
			objMembershipUser.Email = email;
			objMembershipUser.LastActivityDate = DateTime.Now;
			if (user.IsSuperUser)
			{
				objMembershipUser.IsApproved = user.Membership.Approved;
			}
			AspNetSecurity.Membership.UpdateUser(objMembershipUser);
		}
		private bool ValidateUser(int portalId, string username, string password)
		{
			return AspNetSecurity.Membership.ValidateUser(username, password);
		}
		public override bool CanEditProviderProperties
		{
			get { return false; }
		}
		public override int MaxInvalidPasswordAttempts
		{
			get { return AspNetSecurity.Membership.MaxInvalidPasswordAttempts; }
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override int MinNonAlphanumericCharacters
		{
			get { return AspNetSecurity.Membership.MinRequiredNonAlphanumericCharacters; }
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override int MinPasswordLength
		{
			get { return AspNetSecurity.Membership.MinRequiredPasswordLength; }
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override int PasswordAttemptWindow
		{
			get { return AspNetSecurity.Membership.PasswordAttemptWindow; }
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override PasswordFormat PasswordFormat
		{
			get
			{
				switch (AspNetSecurity.Membership.Provider.PasswordFormat)
				{
					case MembershipPasswordFormat.Encrypted:
						return PasswordFormat.Encrypted;
					case MembershipPasswordFormat.Hashed:
						return PasswordFormat.Hashed;
					default:
						return PasswordFormat.Clear;
				}
			}
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override bool PasswordResetEnabled
		{
			get { return AspNetSecurity.Membership.EnablePasswordReset; }
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override bool PasswordRetrievalEnabled
		{
			get { return AspNetSecurity.Membership.EnablePasswordRetrieval; }
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override bool RequiresQuestionAndAnswer
		{
			get { return AspNetSecurity.Membership.RequiresQuestionAndAnswer; }
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override string PasswordStrengthRegularExpression
		{
			get { return AspNetSecurity.Membership.PasswordStrengthRegularExpression; }
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override bool RequiresUniqueEmail
		{
			get { return AspNetSecurity.Membership.Provider.RequiresUniqueEmail; }
			set
			{
				throw new NotSupportedException("Provider properties for AspNetMembershipProvider must be set in web.config");
			}
		}
		public override bool ChangePassword(UserInfo user, string oldPassword, string newPassword)
		{
			bool retValue = false;
			AspNetSecurity.MembershipUser aspnetUser = GetMembershipUser(user);
			if (oldPassword == Null.NullString)
			{
				aspnetUser.UnlockUser();
				oldPassword = aspnetUser.GetPassword();
			}
			retValue = aspnetUser.ChangePassword(oldPassword, newPassword);
			if (retValue && this.PasswordRetrievalEnabled && !this.RequiresQuestionAndAnswer)
			{
				string confirmPassword = aspnetUser.GetPassword();
				if (confirmPassword == newPassword)
				{
					user.Membership.Password = confirmPassword;
					retValue = true;
				}
				else
				{
					retValue = false;
				}
			}
			return retValue;
		}
		public override bool ChangePasswordQuestionAndAnswer(UserInfo user, string password, string passwordQuestion, string passwordAnswer)
		{
			bool retValue = false;
			AspNetSecurity.MembershipUser aspnetUser = GetMembershipUser(user);
			if (password == Null.NullString)
			{
				password = aspnetUser.GetPassword();
			}
			retValue = aspnetUser.ChangePasswordQuestionAndAnswer(password, passwordQuestion, passwordAnswer);
			return retValue;
		}
		public override UserCreateStatus CreateUser(ref UserInfo user)
		{
			UserCreateStatus createStatus;
			try
			{
				UserInfo objVerifyUser = GetUserByUserName(Null.NullInteger, user.Username, false);
				if (objVerifyUser != null)
				{
					if (objVerifyUser.IsSuperUser)
					{
						createStatus = UserCreateStatus.UserAlreadyRegistered;
					}
					else
					{
						if (ValidateUser(objVerifyUser.PortalID, user.Username, user.Membership.Password))
						{
							objVerifyUser = GetUserByUserName(user.PortalID, user.Username, false);
							if (objVerifyUser != null)
							{
								createStatus = UserCreateStatus.UserAlreadyRegistered;
							}
							else
							{
								createStatus = UserCreateStatus.AddUserToPortal;
							}
						}
						else
						{
							createStatus = UserCreateStatus.UsernameAlreadyExists;
						}
					}
				}
				else
				{
					createStatus = UserCreateStatus.AddUser;
				}
				if (createStatus == UserCreateStatus.AddUser)
				{
					createStatus = CreateMemberhipUser(user);
				}
				if (createStatus == UserCreateStatus.Success || createStatus == UserCreateStatus.AddUserToPortal)
				{
					createStatus = CreateDNNUser(ref user);
					if (createStatus == UserCreateStatus.Success)
					{
						ProfileController.UpdateUserProfile(user);
					}
				}
				if (createStatus == UserCreateStatus.UserAlreadyRegistered)
				{
					if (objVerifyUser.IsDeleted)
					{
						objVerifyUser.IsDeleted = false;
						objVerifyUser.Membership.Approved = user.Membership.Approved;
						UpdateUser(objVerifyUser);
						createStatus = UserCreateStatus.Success;
						user.UserID = objVerifyUser.UserID;
					}
				}
			}
			catch (Exception exc)
			{
				DotNetNuke.Services.Exceptions.Exceptions.LogException(exc);
				createStatus = UserCreateStatus.UnexpectedError;
			}
			return createStatus;
		}
		public override bool DeleteUser(UserInfo user)
		{
			bool retValue = true;
			IDataReader dr = null;
			try
			{
				dr = dataProvider.GetRolesByUser(user.UserID, user.PortalID);
				while (dr.Read())
				{
					dataProvider.DeleteUserRole(user.UserID, Convert.ToInt32(dr["RoleId"]));
				}
				dataProvider.DeleteUserPortal(user.UserID, user.PortalID);
			}
			catch (Exception ex)
			{
				DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
				retValue = false;
			}
			finally
			{
				CBO.CloseDataReader(dr, true);
			}
			return retValue;
		}

		/// -----------------------------------------------------------------------------
		/// <summary>
		/// RestoreUser Restores a single User from the Data Store
		/// </summary>
		/// <remarks>
		/// </remarks>
		/// <param name="user">The user to restore from the Data Store.</param>
		/// <returns>A Boolean indicating success or failure.</returns>
		/// <history>
		///     [aprasad]	2/15/2011	created
		/// </history>
		/// -----------------------------------------------------------------------------
		public override bool RestoreUser(UserInfo user)
		{
			bool retValue = true;

			try
			{
				dataProvider.RestoreUser(user.UserID, user.PortalID);
			}
			catch (Exception ex)
			{
				Exceptions.LogException(ex);
				retValue = false;
			}

			return retValue;
		}

		/// -----------------------------------------------------------------------------
		/// <summary>
		/// RemoveUser Removes a single User permanently from the Data Store and Asp.Net Membership
		/// </summary>
		/// <remarks>
		/// </remarks>
		/// <param name="user">The user to permanently remove from the Data Store.</param>
		/// <returns>A Boolean indicating success or failure.</returns>
		/// <history>
		///     [aprasad]	2/15/2011	created
		/// </history>
		/// -----------------------------------------------------------------------------
		public override bool RemoveUser(UserInfo user)
		{
			bool retValue = true;

			try
			{
				dataProvider.RemoveUser(user.UserID, user.PortalID);
				//Prior to removing membership, ensure user is not present in any other portal
				UserInfo otherUser = GetUserByUserName(Null.NullInteger, user.Username);
				if ((otherUser == null))
				{
					DeleteMembershipUser(user);
				}
			}
			catch (Exception ex)
			{
				Exceptions.LogException(ex);
				retValue = false;
			}

			return retValue;
		}

		public override void DeleteUsersOnline(int TimeWindow)
		{
			dataProvider.DeleteUsersOnline(TimeWindow);
		}
		public override string GeneratePassword()
		{
			return GeneratePassword(MinPasswordLength + 4);
		}
		public override string GeneratePassword(int length)
		{
			return AspNetSecurity.Membership.GeneratePassword(length, MinNonAlphanumericCharacters);
		}
		public override ArrayList GetOnlineUsers(int PortalId)
		{
			int totalRecords = 0;
			return UserController.FillUserCollection(PortalId, dataProvider.GetOnlineUsers(PortalId), ref totalRecords);
		}
		public override string GetPassword(UserInfo user, string passwordAnswer)
		{
			string retValue = "";
			bool unLocked = true;
			AspNetSecurity.MembershipUser aspnetUser = GetMembershipUser(user);
			if (aspnetUser.IsLockedOut)
			{
				unLocked = AutoUnlockUser(aspnetUser);
			}
			if (RequiresQuestionAndAnswer)
			{
				retValue = aspnetUser.GetPassword(passwordAnswer);
			}
			else
			{
				retValue = aspnetUser.GetPassword();
			}
			return retValue;
		}
		public override ArrayList GetUnAuthorizedUsers(int portalId, bool includeDeleted, bool superUsersOnly)
		{
			return UserController.FillUserCollection(portalId, dataProvider.GetUnAuthorizedUsers(portalId, includeDeleted, superUsersOnly));
		}

		public override ArrayList GetUnAuthorizedUsers(int portalId)
		{
			return GetUnAuthorizedUsers(portalId, false, false);
		}

		public override ArrayList GetDeletedUsers(int portalId)
		{
			return UserController.FillUserCollection(portalId, dataProvider.GetDeletedUsers(portalId));
		}
		public override UserInfo GetUser(int portalId, int userId)
		{
			IDataReader dr = dataProvider.GetUser(portalId, userId);
			UserInfo objUserInfo = UserController.FillUserInfo(portalId, dr, true);
			return objUserInfo;
		}
		public override UserInfo GetUserByUserName(int portalId, string username)
		{
			IDataReader dr = dataProvider.GetUserByUsername(portalId, username);
			UserInfo objUserInfo = UserController.FillUserInfo(portalId, dr, true);
			return objUserInfo;
		}
		public override int GetUserCountByPortal(int portalId)
		{
			return dataProvider.GetUserCountByPortal(portalId);
		}
		public override void GetUserMembership(ref UserInfo user)
		{
			AspNetSecurity.MembershipUser aspnetUser = null;
			aspnetUser = GetMembershipUser(user);
			FillUserMembership(aspnetUser, user);
			user.Membership.IsOnLine = IsUserOnline(user);
		}
		/// -----------------------------------------------------------------------------
		/// <summary>
		/// GetUsers gets all the users of the portal
		/// </summary>
		/// <remarks>If all records are required, (ie no paging) set pageSize = -1</remarks>
		/// <param name="portalId">The Id of the Portal</param>
		/// <param name="pageIndex">The page of records to return.</param>
		/// <param name="pageSize">The size of the page</param>
		/// <param name="totalRecords">The total no of records that satisfy the criteria.</param>
		/// <param name="includeDeleted">Include Deleted users.</param>
		/// <param name="superUsersOnly">Bring back super users only</param>
		/// <returns>An ArrayList of UserInfo objects.</returns>
		/// <history>
		///     [aprasad]	2/16/2011	created - new overload with Deletion option
		/// </history>
		/// -----------------------------------------------------------------------------
		public override ArrayList GetUsers(int portalId, int pageIndex, int pageSize, ref int totalRecords, bool includeDeleted, bool superUsersOnly)
		{
			if (pageIndex == -1)
			{
				pageIndex = 0;
				pageSize = int.MaxValue;
			}

			return UserController.FillUserCollection(portalId, dataProvider.GetAllUsers(portalId, pageIndex, pageSize, includeDeleted, superUsersOnly), ref totalRecords);
		}

		/// -----------------------------------------------------------------------------
		/// <summary>
		/// GetUsers gets all the non-deleted users of the portal
		/// </summary>
		/// <remarks>If all records are required, (ie no paging) set pageSize = -1</remarks>
		/// <param name="portalId">The Id of the Portal</param>
		/// <param name="pageIndex">The page of records to return.</param>
		/// <param name="pageSize">The size of the page</param>
		/// <param name="totalRecords">The total no of records that satisfy the criteria.</param>
		/// <returns>An ArrayList of UserInfo objects.</returns>
		/// <history>
		///     [cnurse]	12/14/2005	created
		///     [aprasad]	2/16/2011	call new overload with Deleted parameter as False
		/// </history>
		/// -----------------------------------------------------------------------------
		public override ArrayList GetUsers(int portalId, int pageIndex, int pageSize, ref int totalRecords)
		{
			return GetUsers(portalId, pageIndex, pageSize, ref totalRecords, false, false);
		}

		/// -----------------------------------------------------------------------------
		/// <summary>
		/// GetUsersByEmail gets all the users of the portal whose email matches a provided
		/// filter expression
		/// </summary>
		/// <remarks>If all records are required, (ie no paging) set pageSize = -1</remarks>
		/// <param name="portalId">The Id of the Portal</param>
		/// <param name="emailToMatch">The email address to use to find a match.</param>
		/// <param name="pageIndex">The page of records to return.</param>
		/// <param name="pageSize">The size of the page</param>
		/// <param name="totalRecords">The total no of records that satisfy the criteria.</param>
		/// <param name="includeDeleted">Include Deleted users.</param>
		/// <param name="superUsersOnly">Bring back super users only</param>
		/// <returns>An ArrayList of UserInfo objects.</returns>
		/// <history>
		///     [aprasad]	2/16/2011	created - new overload with Deletion option
		/// </history>
		/// -----------------------------------------------------------------------------
		public override ArrayList GetUsersByEmail(int portalId, string emailToMatch, int pageIndex, int pageSize, ref int totalRecords, bool includeDeleted, bool superUsersOnly)
		{
			if (pageIndex == -1)
			{
				pageIndex = 0;
				pageSize = int.MaxValue;
			}

			return UserController.FillUserCollection(portalId, dataProvider.GetUsersByEmail(portalId, emailToMatch, pageIndex, pageSize, includeDeleted, superUsersOnly), ref totalRecords);
		}
		/// -----------------------------------------------------------------------------
		/// <summary>
		/// GetUsersByEmail gets all the users of the portal whose email matches a provided
		/// filter expression
		/// </summary>
		/// <remarks>If all records are required, (ie no paging) set pageSize = -1</remarks>
		/// <param name="portalId">The Id of the Portal</param>
		/// <param name="emailToMatch">The email address to use to find a match.</param>
		/// <param name="pageIndex">The page of records to return.</param>
		/// <param name="pageSize">The size of the page</param>
		/// <param name="totalRecords">The total no of records that satisfy the criteria.</param>
		/// <returns>An ArrayList of UserInfo objects.</returns>
		/// <history>
		///     [cnurse]	12/14/2005	created
		///     [aprasad]	2/16/2011	call new overload with Deleted parameter as False
		/// </history>
		/// -----------------------------------------------------------------------------
		public override ArrayList GetUsersByEmail(int portalId, string emailToMatch, int pageIndex, int pageSize, ref int totalRecords)
		{
			return GetUsersByEmail(portalId, emailToMatch, pageIndex, pageSize, ref totalRecords, false, false);
		}

		/// -----------------------------------------------------------------------------
		/// <summary>
		/// GetUsersByUserName gets all the users of the portal whose username matches a provided
		/// filter expression
		/// </summary>
		/// <remarks>If all records are required, (ie no paging) set pageSize = -1</remarks>
		/// <param name="portalId">The Id of the Portal</param>
		/// <param name="userNameToMatch">The username to use to find a match.</param>
		/// <param name="pageIndex">The page of records to return.</param>
		/// <param name="pageSize">The size of the page</param>
		/// <param name="totalRecords">The total no of records that satisfy the criteria.</param>
		/// <param name="includeDeleted">Include Deleted users.</param>
		/// <param name="superUsersOnly">Bring back super users only</param>
		/// <returns>An ArrayList of UserInfo objects.</returns>
		/// <history>
		///     [aprasad]	2/16/2011	created - new overload with Deletion option
		/// </history>
		/// -----------------------------------------------------------------------------
		public override ArrayList GetUsersByUserName(int portalId, string userNameToMatch, int pageIndex, int pageSize, ref int totalRecords, bool includeDeleted, bool superUsersOnly)
		{
			if (pageIndex == -1)
			{
				pageIndex = 0;
				pageSize = int.MaxValue;
			}

			return UserController.FillUserCollection(portalId, dataProvider.GetUsersByUsername(portalId, userNameToMatch, pageIndex, pageSize, includeDeleted, superUsersOnly), ref totalRecords);
		}

		/// -----------------------------------------------------------------------------
		/// <summary>
		/// GetUsersByUserName gets all the users of the portal whose username matches a provided
		/// filter expression
		/// </summary>
		/// <remarks>If all records are required, (ie no paging) set pageSize = -1</remarks>
		/// <param name="portalId">The Id of the Portal</param>
		/// <param name="userNameToMatch">The username to use to find a match.</param>
		/// <param name="pageIndex">The page of records to return.</param>
		/// <param name="pageSize">The size of the page</param>
		/// <param name="totalRecords">The total no of records that satisfy the criteria.</param>
		/// <returns>An ArrayList of UserInfo objects.</returns>
		/// <history>
		///     [cnurse]	12/14/2005	created
		///     [aprasad]	2/16/2011	call new overload with Deleted parameter as False
		/// </history>
		/// -----------------------------------------------------------------------------
		public override ArrayList GetUsersByUserName(int portalId, string userNameToMatch, int pageIndex, int pageSize, ref int totalRecords)
		{
			return GetUsersByUserName(portalId, userNameToMatch, pageIndex, pageSize, ref totalRecords, false, false);
		}

		/// -----------------------------------------------------------------------------
		/// <summary>
		/// GetUsersByProfileProperty gets all the users of the portal whose profile matches
		/// the profile property pased as a parameter
		/// </summary>
		/// <remarks>
		/// </remarks>
		/// <param name="portalId">The Id of the Portal</param>
		/// <param name="propertyName">The name of the property being matched.</param>
		/// <param name="propertyValue">The value of the property being matched.</param>
		/// <param name="pageIndex">The page of records to return.</param>
		/// <param name="pageSize">The size of the page</param>
		/// <param name="totalRecords">The total no of records that satisfy the criteria.</param>
		/// <param name="includeDeleted">Include Deleted users.</param>
		/// <param name="superUsersOnly">Bring back super users only</param>
		/// <returns>An ArrayList of UserInfo objects.</returns>
		/// <history>
		///     [aprasad]	2/16/2011	created - new overload with Deletion option
		/// </history>
		/// -----------------------------------------------------------------------------
		public override ArrayList GetUsersByProfileProperty(int portalId, string propertyName, string propertyValue, int pageIndex, int pageSize, ref int totalRecords, bool includeDeleted, bool superUsersOnly)
		{
			if (pageIndex == -1)
			{
				pageIndex = 0;
				pageSize = int.MaxValue;
			}

			return UserController.FillUserCollection(portalId, dataProvider.GetUsersByProfileProperty(portalId, propertyName, propertyValue, pageIndex, pageSize, includeDeleted, superUsersOnly), ref totalRecords);
		}

		/// -----------------------------------------------------------------------------
		/// <summary>
		/// GetUsersByProfileProperty gets all the users of the portal whose profile matches
		/// the profile property pased as a parameter
		/// </summary>
		/// <remarks>
		/// </remarks>
		/// <param name="portalId">The Id of the Portal</param>
		/// <param name="propertyName">The name of the property being matched.</param>
		/// <param name="propertyValue">The value of the property being matched.</param>
		/// <param name="pageIndex">The page of records to return.</param>
		/// <param name="pageSize">The size of the page</param>
		/// <param name="totalRecords">The total no of records that satisfy the criteria.</param>
		/// <returns>An ArrayList of UserInfo objects.</returns>
		/// <history>
		///     [cnurse]	02/01/2006	created
		///     [aprasad]	2/16/2011	call new overload with Deleted parameter as False
		/// </history>
		/// -----------------------------------------------------------------------------
		public override ArrayList GetUsersByProfileProperty(int portalId, string propertyName, string propertyValue, int pageIndex, int pageSize, ref int totalRecords)
		{
			return GetUsersByProfileProperty(portalId, propertyName, propertyValue, pageIndex, pageSize, ref totalRecords, false, false);
		}
		public override bool IsUserOnline(UserInfo user)
		{
			bool isOnline = false;
			UserOnlineController objUsersOnline = new UserOnlineController();
			if (objUsersOnline.IsEnabled())
			{
				Hashtable userList = objUsersOnline.GetUserList();
				OnlineUserInfo onlineUser = (OnlineUserInfo)userList[user.UserID.ToString()];
				if (onlineUser != null)
				{
					isOnline = true;
				}
				else
				{
					onlineUser = (OnlineUserInfo)CBO.FillObject(dataProvider.GetOnlineUser(user.UserID), typeof(OnlineUserInfo));
					if (onlineUser != null)
					{
						isOnline = true;
					}
				}
			}
			return isOnline;
		}
		public override string ResetPassword(UserInfo user, string passwordAnswer)
		{
			string retValue = "";
			AspNetSecurity.MembershipUser aspnetUser = GetMembershipUser(user);
			if (RequiresQuestionAndAnswer)
			{
				retValue = aspnetUser.ResetPassword(passwordAnswer);
			}
			else
			{
				retValue = aspnetUser.ResetPassword();
			}
			return retValue;
		}
		public override bool UnLockUser(UserInfo user)
		{
			AspNetSecurity.MembershipUser objMembershipUser;
			objMembershipUser = AspNetSecurity.Membership.GetUser(user.Username);
			return objMembershipUser.UnlockUser();
		}
		public override void UpdateUser(UserInfo user)
		{
			PortalSecurity objSecurity = new PortalSecurity();
			string firstName = objSecurity.InputFilter(user.FirstName, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			string lastName = objSecurity.InputFilter(user.LastName, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			string email = objSecurity.InputFilter(user.Email, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			string displayName = objSecurity.InputFilter(user.DisplayName, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
			bool updatePassword = user.Membership.UpdatePassword;
			bool isApproved = user.Membership.Approved;
			if (String.IsNullOrEmpty(displayName))
			{
				displayName = firstName + " " + lastName;
			}
			UpdateUserMembership(user);
			dataProvider.UpdateUser(user.UserID, user.PortalID, firstName, lastName, email, displayName, updatePassword, isApproved, user.RefreshRoles, user.LastIPAddress,
			user.IsDeleted, UserController.GetCurrentUserInfo().UserID);
			ProfileController.UpdateUserProfile(user);
		}
		public override void UpdateUsersOnline(Hashtable UserList)
		{
			dataProvider.UpdateUsersOnline(UserList);
		}
		public override UserInfo UserLogin(int portalId, string username, string password, string verificationCode, ref UserLoginStatus loginStatus)
		{
			return UserLogin(portalId, username, password, "DNN", verificationCode, ref loginStatus);
		}
		public override UserInfo UserLogin(int portalId, string username, string password, string authType, string verificationCode, ref UserLoginStatus loginStatus)
		{
			loginStatus = UserLoginStatus.LOGIN_FAILURE;
			UserInfo user = null;
			if (authType == "DNN")
			{
				user = GetUserByUserName(portalId, username, false);
			}
			else
			{
				user = GetUserByAuthToken(portalId, username, authType);
			}
			if (user != null && !user.IsDeleted)
			{
				AspNetSecurity.MembershipUser aspnetUser = null;
				aspnetUser = GetMembershipUser(user);
				FillUserMembership(aspnetUser, user);
				if (aspnetUser.IsLockedOut)
				{
					if (AutoUnlockUser(aspnetUser))
					{
						user.Membership.LockedOut = false;
					}
					else
					{
						loginStatus = UserLoginStatus.LOGIN_USERLOCKEDOUT;
					}
				}
				if (user.Membership.Approved == false && user.IsSuperUser == false)
				{
					if (verificationCode == (portalId.ToString() + "-" + user.UserID))
					{
						user.Membership.Approved = true;
						UpdateUser(user);
					}
					else
					{
						loginStatus = UserLoginStatus.LOGIN_USERNOTAPPROVED;
					}
				}
				bool bValid = false;
				if (loginStatus != UserLoginStatus.LOGIN_USERLOCKEDOUT && loginStatus != UserLoginStatus.LOGIN_USERNOTAPPROVED)
				{
					if (authType == "DNN")
					{
						if (user.IsSuperUser)
						{
							if (ValidateUser(Null.NullInteger, username, password))
							{
								loginStatus = UserLoginStatus.LOGIN_SUPERUSER;
								bValid = true;
							}
						}
						else
						{
							if (ValidateUser(portalId, username, password))
							{
								loginStatus = UserLoginStatus.LOGIN_SUCCESS;
								bValid = true;
							}
						}
					}
					else
					{
						if (user.IsSuperUser)
						{
							loginStatus = UserLoginStatus.LOGIN_SUPERUSER;
							bValid = true;
						}
						else
						{
							loginStatus = UserLoginStatus.LOGIN_SUCCESS;
							bValid = true;
						}
					}
				}
				if (!bValid)
				{
					user = null;
				}
			}
			else
			{
				user = null;
			}
			return user;
		}
		public override ArrayList GetUnAuthorizedUsers(int portalId, bool isHydrated)
		{
			return GetUnAuthorizedUsers(portalId);
		}
		public override UserInfo GetUser(int portalId, int userId, bool isHydrated)
		{
			return GetUser(portalId, userId);
		}
		public override UserInfo GetUserByUserName(int portalId, string username, bool isHydrated)
		{
			return GetUserByUserName(portalId, username);
		}
		public override ArrayList GetUsers(int portalId, bool isHydrated, int pageIndex, int pageSize, ref int totalRecords)
		{
			return GetUsers(portalId, pageIndex, pageSize, ref totalRecords);
		}
		public override ArrayList GetUsersByEmail(int portalId, bool isHydrated, string emailToMatch, int pageIndex, int pageSize, ref int totalRecords)
		{
			return GetUsersByEmail(portalId, emailToMatch, pageIndex, pageSize, ref totalRecords);
		}
		public override ArrayList GetUsersByUserName(int portalId, bool isHydrated, string userNameToMatch, int pageIndex, int pageSize, ref int totalRecords)
		{
			return GetUsersByUserName(portalId, userNameToMatch, pageIndex, pageSize, ref totalRecords);
		}
		public override ArrayList GetUsersByProfileProperty(int portalId, bool isHydrated, string propertyName, string propertyValue, int pageIndex, int pageSize, ref int totalRecords)
		{
			return GetUsersByProfileProperty(portalId, propertyName, propertyValue, pageIndex, pageSize, ref totalRecords);
		}
	}
}
